home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / newmat08.zip / MYEXCEPT.H < prev    next >
C/C++ Source or Header  |  1995-01-18  |  10KB  |  328 lines

  1. //$$ myexcept.h                          Exception handling classes
  2.  
  3. // A set of classes to simulate exceptions in C++
  4. //
  5. //   Partially copied from Carlos Vidal's article in the C users' journal
  6. //   September 1992, pp 19-28
  7. //
  8. //   Operations defined
  9. //      Try {     }
  10. //      Throw ( exception object )
  11. //      Catch ( exception class ) {      }
  12. //      CatchAll {      }
  13. //      CatchAndThrow
  14. //
  15. //   All catch lists must end with a CatchAll or CatchAndThrow statement
  16. //   but not both.
  17. //
  18. //   When exceptions are finally implemented replace Try, Throw, Catch,
  19. //   CatchAll, CatchAndThrow by try, throw, catch, catch(...), and {}.
  20. //
  21. //   All exception classes must be derived from Exception, have no non-static
  22. //   variables and must include functions
  23. //
  24. //      static long st_type()  { return 2; }
  25. //      long type() const { return 2; }
  26. //
  27. //   where 2 is replaced by a prime number unique to the exception class.
  28. //   See notes for use with levels of exceptions.
  29. //
  30.  
  31. #ifndef EXCEPTION_LIB
  32. #define EXCEPTION_LIB
  33.  
  34. void Terminate();
  35.  
  36. /*********** classes for setting up exceptions and reporting ***************/
  37.  
  38. class Exception;
  39.  
  40. class Tracer                                    // linked list showing how
  41. {                                               // we got here
  42.     char* entry;
  43.     Tracer* previous;
  44. public:
  45.     Tracer(char*);
  46.     ~Tracer();
  47.     void ReName(char*);
  48.     friend class Exception;
  49. };
  50.  
  51.  
  52. class Exception                                 // The base exception class
  53. {
  54. protected:
  55.    Exception() {}
  56. public:
  57.    static Tracer* last;                         // points to Tracer list
  58.    static long st_type() { return 1; }
  59.    virtual long type() const { return 1; }
  60.    static void PrintTrace(Boolean=FALSE);       // for printing trace
  61.    friend class Tracer;
  62.    Exception(int action);
  63.    Exception(const Exception&) {}               // don't do anything
  64. };
  65.  
  66.  
  67. inline Tracer::Tracer(char* e)
  68.    : entry(e), previous(Exception::last) { Exception::last = this; }
  69.  
  70. inline Tracer::~Tracer() { Exception::last = previous; }
  71.  
  72. inline void Tracer::ReName(char* e) { entry=e; }
  73.  
  74.  
  75. #ifdef SimulateExceptions                // SimulateExceptions
  76.  
  77. #include <setjmp.h>
  78.  
  79.  
  80. /************** the definitions of Try, Throw and Catch *******************/
  81.  
  82.  
  83. class JumpItem;
  84. class Janitor;
  85.  
  86. class JumpBase         // pointer to a linked list of jmp_buf s
  87. {
  88. public:
  89.    static JumpItem *jl;
  90.    static long type;                    // type id. of last exception
  91.    static jmp_buf env;
  92. };
  93.  
  94. class JumpItem         // an item in a linked list of jmp_buf s
  95. {
  96. public:
  97.    JumpItem *ji;
  98.    jmp_buf env;
  99.    Tracer* trace;                     // to keep check on Tracer items
  100.    Janitor* janitor;                  // list of items for cleanup
  101.    JumpItem() : trace(0), janitor(0), ji(JumpBase::jl)
  102.       { JumpBase::jl = this; }
  103.    ~JumpItem() { JumpBase::jl = ji; }
  104. };
  105.  
  106. void Throw(const Exception& exc);
  107.  
  108. void Throw();
  109.  
  110. #define Try                                             \
  111.       if (!setjmp( JumpBase::jl->env )) {               \
  112.       JumpBase::jl->trace = Exception::last;            \
  113.       JumpItem JI387256156;
  114.  
  115. #define Bounce Throw()
  116.  
  117. #define Catch(EXCEPTION)                                \
  118.    } else if (JumpBase::type % EXCEPTION::st_type() == 0) {
  119.  
  120. #define CatchAll } else
  121.  
  122. #define CatchAndThrow  } else Throw();
  123.  
  124.  
  125.  
  126. /******************* cleanup heap following Throw ************************/
  127.  
  128. class Janitor
  129. {
  130. protected:
  131.    static Boolean do_not_link;                  // set when new is called
  132.    Boolean OnStack;                             // false if created by new
  133. public:
  134.    Janitor* NextJanitor;
  135.    virtual void CleanUp() {}
  136.    Janitor();
  137.     virtual ~Janitor();
  138. };
  139.  
  140.  
  141. // A tiresome old trick for initializing the Janitor class
  142. // this is needed for classes derived from Janitor which have objects
  143. // declared globally
  144.  
  145. class JanitorInitializer
  146. {
  147. public:
  148.    JanitorInitializer();
  149. private:
  150.    static int ref_count;
  151. };
  152.  
  153. static JanitorInitializer JanInit;
  154.  
  155. #endif                                // end of SimulateExceptions
  156.  
  157. #ifdef UseExceptions
  158.  
  159. #define Try try
  160. #define Throw(E) throw E
  161. #define Bounce throw
  162. #define Catch catch
  163. #define CatchAll catch(...)
  164. #define CatchAndThrow {}
  165.  
  166. #endif                                // end of UseExceptions
  167.  
  168.  
  169. #ifdef DisableExceptions              // Disable exceptions
  170.  
  171. #define Try {
  172. #define Bounce Throw()
  173. #define Catch(EXCEPTION) } if (FALSE) {
  174. #define CatchAll } if (FALSE)
  175. #define CatchAndThrow }
  176.  
  177. inline void Throw() { Terminate(); }
  178. inline void Throw(const Exception&) { Terminate(); }
  179.  
  180.  
  181. #endif                                // end of DisableExceptions
  182.  
  183. #ifndef SimulateExceptions            // ! SimulateExceptions
  184.  
  185. class Janitor                         // a dummy version
  186. {
  187. public:
  188.    virtual void CleanUp() {}
  189.    Janitor() {}
  190.    virtual ~Janitor() {}
  191. };
  192.  
  193. #endif                                // end of ! SimulateExceptions
  194.  
  195.  
  196.  
  197.  
  198. #ifdef DO_FREE_CHECK                          // DO_FREE_CHECK
  199. // Routines for tracing whether new and delete calls are balanced
  200.  
  201. class FreeCheck;
  202.  
  203. class FreeCheckLink
  204. {
  205. protected:
  206.    FreeCheckLink* next;
  207.    void* ClassStore;
  208.    FreeCheckLink();
  209.    virtual void Report()=0;                   // print details of link
  210.    friend class FreeCheck;
  211. };
  212.  
  213. class FCLClass : public FreeCheckLink         // for registering objects
  214. {
  215.    char* ClassName;
  216.    FCLClass(void* t, char* name);
  217.    void Report();
  218.    friend class FreeCheck;
  219. };
  220.  
  221. class FCLRealArray : public FreeCheckLink     // for registering real arrays
  222. {
  223.    char* Operation;
  224.    int size;
  225.    FCLRealArray(void* t, char* o, int s);
  226.    void Report();
  227.    friend class FreeCheck;
  228. };
  229.  
  230. class FCLIntArray : public FreeCheckLink     // for registering int arrays
  231. {
  232.    char* Operation;
  233.    int size;
  234.    FCLIntArray(void* t, char* o, int s);
  235.    void Report();
  236.    friend class FreeCheck;
  237. };
  238.  
  239.  
  240. class FreeCheck
  241. {
  242.    static FreeCheckLink* next;
  243.    static int BadDelete;
  244. public:
  245.    static void Register(void*, char*);
  246.    static void DeRegister(void*, char*);
  247.    static void RegisterR(void*, char*, int);
  248.    static void DeRegisterR(void*, char*, int);
  249.    static void RegisterI(void*, char*, int);
  250.    static void DeRegisterI(void*, char*, int);
  251.    static void Status();
  252.    friend class FreeCheckLink;
  253.    friend class FCLClass;
  254.    friend class FCLRealArray;
  255.    friend class FCLIntArray;
  256. };
  257.  
  258. #define FREE_CHECK(Class)                                                  \
  259. public:                                                                    \
  260.    void* operator new(size_t size)                                         \
  261.    {                                                                       \
  262.       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  263.       return t;                                                            \
  264.    }                                                                       \
  265.    void operator delete(void* t)                                           \
  266.    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  267.  
  268.  
  269. #ifdef SimulateExceptions         // SimulateExceptions
  270.  
  271. #define NEW_DELETE(Class)                                                  \
  272. public:                                                                    \
  273.     void* operator new(size_t size)                                         \
  274.     {                                                                       \
  275.         do_not_link=TRUE;                                                    \
  276.         void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  277.         return t;                                                            \
  278.     }                                                                       \
  279.     void operator delete(void* t)                                           \
  280.     { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  281.  
  282.  
  283. #endif                           // end of SimulateExceptions
  284.  
  285.  
  286. #define MONITOR_REAL_NEW(Operation, Size, Pointer)                         \
  287.     FreeCheck::RegisterR(Pointer, Operation, Size);
  288. #define MONITOR_INT_NEW(Operation, Size, Pointer)                          \
  289.     FreeCheck::RegisterI(Pointer, Operation, Size);
  290. #define MONITOR_REAL_DELETE(Operation, Size, Pointer)                      \
  291.     FreeCheck::DeRegisterR(Pointer, Operation, Size);
  292. #define MONITOR_INT_DELETE(Operation, Size, Pointer)                       \
  293.     FreeCheck::DeRegisterI(Pointer, Operation, Size);
  294.  
  295. #else                            // DO_FREE_CHECK not defined
  296.  
  297. #define FREE_CHECK(Class) public:
  298. #define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
  299. #define MONITOR_INT_NEW(Operation, Size, Pointer) {}
  300. #define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
  301. #define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
  302.  
  303.  
  304. #ifdef SimulateExceptions         // SimulateExceptions
  305.  
  306.  
  307. #define NEW_DELETE(Class)                                                  \
  308. public:                                                                    \
  309.     void* operator new(size_t size)                                         \
  310.     { do_not_link=TRUE; void* t = ::operator new(size); return t; }         \
  311.     void operator delete(void* t) { ::operator delete(t); }
  312.  
  313. #endif                            // end of SimulateExceptions
  314.  
  315. #endif                            // end of ! DO_FREE_CHECK
  316.  
  317. #ifndef SimulateExceptions        // ! SimulateExceptions
  318.  
  319. #define NEW_DELETE(Class) FREE_CHECK(Class)
  320.  
  321. #endif                            // end of ! SimulateExceptions
  322.  
  323. #endif                            // end of ! EXCEPTION_LIB
  324.  
  325.  
  326.  
  327.  
  328.